#ifndef _CHECKPOINT_CKPT_HDR_H_
#define _CHECKPOINT_CKPT_HDR_H_
/*
 *  Generic container checkpoint-restart
 *
 *  Copyright (C) 2008-2010 Oren Laadan
 *
 *  This file is subject to the terms and conditions of the GNU General Public
 *  License.  See the file COPYING in the main directory of the Linux
 *  distribution for more details.
 */

//#include <linux/types.h>
//#include <linux/socket.h>
//#include <linux/un.h>
//#include <linux/in.h>
//#include <linux/in6.h>
#include <proc.h>
#include <slab.h>
#include <string.h>
#include <sync.h>
#include <pmm.h>
#include <error.h>
#include <sched.h>
#include <elf.h>
#include <vmm.h>
#include <trap.h>
#include <unistd.h>
#include <stdio.h>
#include <sched.h>
#include <sync.h>
#include <stdlib.h>
#include <assert.h>
#include <elf.h>
#include <fs.h>
#include <vfs.h>
#include <sysfile.h>
#include <swap.h>
#include <mbox.h>
#include <kio.h>
#include <stdio.h>
#include <mp.h>

// U11 : magic nuber macro definiat
#define CHECKPOINT_MAGIC_HEAD  0x00feed0cc0a2d200LL
#define CHECKPOINT_MAGIC_TAIL  0x002d2a0cc0deef00LL


/*
 * /usr/include/linux/security.h is not exported to userspace, so
 * we need this value here for userspace restart.c to read.
 *
 * CHECKPOINT_LSM_NAME_MAX should be SECURITY_NAME_MAX
 * security_may_restart() has a BUILD_BUG_ON to enforce that.
 */
#define CHECKPOINT_LSM_NAME_MAX 10

/*
 * Macros to help generate a build break if an ambiguous type changes
 * in such a way that the size differs from the unambiguous type we
 * actually write to the checkpoint stream.
 *
 * Examples:
 *
 * CKPT_BUILD_BUG_ON_MISMATCH(short, uint16_t);
 * CKPT_BUILD_BUG_ON_MISMATCH(CKPT_STRUCT_MEMBER(mystruct, mymember),
 *                            CKPT_STRUCT_MEMBER(ckpt_hdr_foo, bar));
 *
 */
#define CKPT_STRUCT_MEMBER(type, member) (((struct type *)(NULL))->member)
#define CKPT_BUILD_BUG_ON_MISMATCH(a, b) (BUILD_BUG_ON(sizeof(a) != sizeof(b)))

/*
 * To maintain compatibility between 32-bit and 64-bit architecture flavors,
 * keep data 64-bit aligned: use padding for structure members, and use
 * __attribute__((aligned (8))) for the entire structure.
 *
 * Quoting Arnd Bergmann:
 *   "This structure has an odd multiple of 32-bit members, which means
 *   that if you put it into a larger structure that also contains 64-bit
 *   members, the larger structure may get different alignment on x86-32
 *   and x86-64, which you might want to avoid. I can't tell if this is
 *   an actual problem here. ... In this case, I'm pretty sure that
 *   sizeof(ckpt_hdr_task) on x86-32 is different from x86-64, since it
 *   will be 32-bit aligned on x86-32."
 */

/*
 * header format: 'struct ckpt_hdr' must prefix all other headers. Therfore
 * when a header is passed around, the information about it (type, size)
 * is readily available. Structs that include a struct ckpt_hdr are named
 * struct ckpt_hdr_* by convention (usualy the struct ckpt_hdr is the first
 * member).
 */
struct ckpt_hdr {
	uint32_t type;
	uint32_t len;
} __attribute__((aligned(8)));


//#include <asm/termbits.h>
#include <asm_checkpoint_hdr.h>


/* header types */
enum {
	CKPT_HDR_HEADER = 1,
#define CKPT_HDR_HEADER CKPT_HDR_HEADER
	CKPT_HDR_HEADER_ARCH,
#define CKPT_HDR_HEADER_ARCH CKPT_HDR_HEADER_ARCH
	CKPT_HDR_CONTAINER,
#define CKPT_HDR_CONTAINER CKPT_HDR_CONTAINER
	CKPT_HDR_BUFFER,
#define CKPT_HDR_BUFFER CKPT_HDR_BUFFER
	CKPT_HDR_STRING,
#define CKPT_HDR_STRING CKPT_HDR_STRING
	CKPT_HDR_OBJREF,
#define CKPT_HDR_OBJREF CKPT_HDR_OBJREF
	CKPT_HDR_LSM_INFO,
#define CKPT_HDR_LSM_INFO CKPT_HDR_LSM_INFO
	CKPT_HDR_SECURITY,
#define CKPT_HDR_SECURITY CKPT_HDR_SECURITY

	CKPT_HDR_PIDS = 101,
#define CKPT_HDR_PIDS CKPT_HDR_PIDS
	CKPT_HDR_TREE,
#define CKPT_HDR_TREE CKPT_HDR_TREE
	CKPT_HDR_TASK,
#define CKPT_HDR_TASK CKPT_HDR_TASK
	CKPT_HDR_TASK_NS,
#define CKPT_HDR_TASK_NS CKPT_HDR_TASK_NS
	CKPT_HDR_TASK_OBJS,
#define CKPT_HDR_TASK_OBJS CKPT_HDR_TASK_OBJS
	CKPT_HDR_RESTART_BLOCK,
#define CKPT_HDR_RESTART_BLOCK CKPT_HDR_RESTART_BLOCK
	CKPT_HDR_THREAD,
#define CKPT_HDR_THREAD CKPT_HDR_THREAD
	CKPT_HDR_CPU,
#define CKPT_HDR_CPU CKPT_HDR_CPU
	CKPT_HDR_NS,
#define CKPT_HDR_NS CKPT_HDR_NS
	CKPT_HDR_UTS_NS,
#define CKPT_HDR_UTS_NS CKPT_HDR_UTS_NS
	CKPT_HDR_IPC_NS,
#define CKPT_HDR_IPC_NS CKPT_HDR_IPC_NS
	CKPT_HDR_MNT_NS,
#define CKPT_HDR_MNT_NS CKPT_HDR_MNT_NS
	CKPT_HDR_CAPABILITIES,
#define CKPT_HDR_CAPABILITIES CKPT_HDR_CAPABILITIES
	CKPT_HDR_USER_NS,
#define CKPT_HDR_USER_NS CKPT_HDR_USER_NS
	CKPT_HDR_CRED,
#define CKPT_HDR_CRED CKPT_HDR_CRED
	CKPT_HDR_USER,
#define CKPT_HDR_USER CKPT_HDR_USER
	CKPT_HDR_GROUPINFO,
#define CKPT_HDR_GROUPINFO CKPT_HDR_GROUPINFO
	CKPT_HDR_TASK_CREDS,
#define CKPT_HDR_TASK_CREDS CKPT_HDR_TASK_CREDS

	/* 201-299: reserved for arch-dependent */

	CKPT_HDR_FILE_TABLE = 301,
#define CKPT_HDR_FILE_TABLE CKPT_HDR_FILE_TABLE
	CKPT_HDR_FILE_DESC,
#define CKPT_HDR_FILE_DESC CKPT_HDR_FILE_DESC
	CKPT_HDR_FILE_NAME,
#define CKPT_HDR_FILE_NAME CKPT_HDR_FILE_NAME
	CKPT_HDR_FILE,
#define CKPT_HDR_FILE CKPT_HDR_FILE
	CKPT_HDR_PIPE_BUF,
#define CKPT_HDR_PIPE_BUF CKPT_HDR_PIPE_BUF
	CKPT_HDR_TTY,
#define CKPT_HDR_TTY CKPT_HDR_TTY
	CKPT_HDR_TTY_LDISC,
#define CKPT_HDR_TTY_LDISC CKPT_HDR_TTY_LDISC
	CKPT_HDR_EPOLL_ITEMS,  /* must be after file-table */
#define CKPT_HDR_EPOLL_ITEMS CKPT_HDR_EPOLL_ITEMS

	CKPT_HDR_MM = 401,
#define CKPT_HDR_MM CKPT_HDR_MM
	CKPT_HDR_VMA,
#define CKPT_HDR_VMA CKPT_HDR_VMA
	CKPT_HDR_PGARR,
#define CKPT_HDR_PGARR CKPT_HDR_PGARR
	CKPT_HDR_HPAGE,
#define CKPT_HDR_HPAGE CKPT_HDR_HPAGE
	CKPT_HDR_MM_CONTEXT,
#define CKPT_HDR_MM_CONTEXT CKPT_HDR_MM_CONTEXT

	CKPT_HDR_FS = 451,  /* must be after file-table, mm */
#define CKPT_HDR_FS CKPT_HDR_FS

	CKPT_HDR_IPC = 501,
#define CKPT_HDR_IPC CKPT_HDR_IPC
	CKPT_HDR_IPC_SHM,
#define CKPT_HDR_IPC_SHM CKPT_HDR_IPC_SHM
	CKPT_HDR_IPC_MSG,
#define CKPT_HDR_IPC_MSG CKPT_HDR_IPC_MSG
	CKPT_HDR_IPC_MSG_MSG,
#define CKPT_HDR_IPC_MSG_MSG CKPT_HDR_IPC_MSG_MSG
	CKPT_HDR_IPC_SEM,
#define CKPT_HDR_IPC_SEM CKPT_HDR_IPC_SEM
	CKPT_HDR_TASK_SEM_UNDO_LIST,
#define CKPT_HDR_TASK_SEM_UNDO_LIST CKPT_HDR_TASK_SEM_UNDO_LIST
	CKPT_HDR_TASK_SEM_UNDO,
#define CKPT_HDR_TASK_SEM_UNDO CKPT_HDR_TASK_SEM_UNDO

	CKPT_HDR_SIGHAND = 601,
#define CKPT_HDR_SIGHAND CKPT_HDR_SIGHAND
	CKPT_HDR_SIGNAL,
#define CKPT_HDR_SIGNAL CKPT_HDR_SIGNAL
	CKPT_HDR_SIGNAL_TASK,
#define CKPT_HDR_SIGNAL_TASK CKPT_HDR_SIGNAL_TASK
	CKPT_HDR_SIGPENDING,
#define CKPT_HDR_SIGPENDING CKPT_HDR_SIGPENDING

	CKPT_HDR_SOCKET = 701,
#define CKPT_HDR_SOCKET CKPT_HDR_SOCKET
	CKPT_HDR_SOCKET_QUEUE,
#define CKPT_HDR_SOCKET_QUEUE CKPT_HDR_SOCKET_QUEUE
	CKPT_HDR_SOCKET_BUFFER,
#define CKPT_HDR_SOCKET_BUFFER CKPT_HDR_SOCKET_BUFFER
	CKPT_HDR_SOCKET_FRAG,
#define CKPT_HDR_SOCKET_FRAG CKPT_HDR_SOCKET_FRAG
	CKPT_HDR_SOCKET_UNIX,
#define CKPT_HDR_SOCKET_UNIX CKPT_HDR_SOCKET_UNIX
	CKPT_HDR_SOCKET_INET,
#define CKPT_HDR_SOCKET_INET CKPT_HDR_SOCKET_INET
	CKPT_HDR_NET_NS,
#define CKPT_HDR_NET_NS CKPT_HDR_NET_NS
	CKPT_HDR_NETDEV,
#define CKPT_HDR_NETDEV CKPT_HDR_NETDEV
	CKPT_HDR_NETDEV_ADDR,
#define CKPT_HDR_NETDEV_ADDR CKPT_HDR_NETDEV_ADDR

	CKPT_HDR_TAIL = 9001,
#define CKPT_HDR_TAIL CKPT_HDR_TAIL

	CKPT_HDR_ERROR = 9999,
#define CKPT_HDR_ERROR CKPT_HDR_ERROR
};

/* architecture */
enum {
	/* do not change order (will break ABI) */
	CKPT_ARCH_i386 = 1,
#define CKPT_ARCH_i386 CKPT_ARCH_i386
	CKPT_ARCH_X86_64,
#define CKPT_ARCH_X86_64 CKPT_ARCH_X86_64
	CKPT_ARCH_S390X,
#define CKPT_ARCH_S390X CKPT_ARCH_S390X
};

/* shared objrects (objref) */
struct ckpt_hdr_objref {
	struct ckpt_hdr h;
	uint32_t objtype;
	int32_t objref;
} __attribute__((aligned(8)));

/* shared objects types */
enum obj_type {
	CKPT_OBJ_IGNORE = 0,
#define CKPT_OBJ_IGNORE CKPT_OBJ_IGNORE
	CKPT_OBJ_PID,
#define CKPT_OBJ_PID CKPT_OBJ_PID
	CKPT_OBJ_INODE,
#define CKPT_OBJ_INODE CKPT_OBJ_INODE
	CKPT_OBJ_FILE_TABLE,
#define CKPT_OBJ_FILE_TABLE CKPT_OBJ_FILE_TABLE
	CKPT_OBJ_FILE,
#define CKPT_OBJ_FILE CKPT_OBJ_FILE
	CKPT_OBJ_MM,
#define CKPT_OBJ_MM CKPT_OBJ_MM
	CKPT_OBJ_FS,
#define CKPT_OBJ_FS CKPT_OBJ_FS
	CKPT_OBJ_SIGHAND,
#define CKPT_OBJ_SIGHAND CKPT_OBJ_SIGHAND
	CKPT_OBJ_SIGNAL,
#define CKPT_OBJ_SIGNAL CKPT_OBJ_SIGNAL
	CKPT_OBJ_NS,
#define CKPT_OBJ_NS CKPT_OBJ_NS
	CKPT_OBJ_UTS_NS,
#define CKPT_OBJ_UTS_NS CKPT_OBJ_UTS_NS
	CKPT_OBJ_IPC_NS,
#define CKPT_OBJ_IPC_NS CKPT_OBJ_IPC_NS
	CKPT_OBJ_MNT_NS,
#define CKPT_OBJ_MNT_NS CKPT_OBJ_MNT_NS
	CKPT_OBJ_USER_NS,
#define CKPT_OBJ_USER_NS CKPT_OBJ_USER_NS
	CKPT_OBJ_CRED,
#define CKPT_OBJ_CRED CKPT_OBJ_CRED
	CKPT_OBJ_USER,
#define CKPT_OBJ_USER CKPT_OBJ_USER
	CKPT_OBJ_GROUPINFO,
#define CKPT_OBJ_GROUPINFO CKPT_OBJ_GROUPINFO
	CKPT_OBJ_SOCK,
#define CKPT_OBJ_SOCK CKPT_OBJ_SOCK
	CKPT_OBJ_TTY,
#define CKPT_OBJ_TTY CKPT_OBJ_TTY
	CKPT_OBJ_SECURITY_PTR,
#define CKPT_OBJ_SECURITY_PTR CKPT_OBJ_SECURITY_PTR
	CKPT_OBJ_SECURITY,
#define CKPT_OBJ_SECURITY CKPT_OBJ_SECURITY
	CKPT_OBJ_NET_NS,
#define CKPT_OBJ_NET_NS CKPT_OBJ_NET_NS
	CKPT_OBJ_NETDEV,
#define CKPT_OBJ_NETDEV CKPT_OBJ_NETDEV
	CKPT_OBJ_SEM_UNDO,
#define CKPT_OBJ_SEM_UNDO CKPT_OBJ_SEM_UNDO
	CKPT_OBJ_MAX
#define CKPT_OBJ_MAX CKPT_OBJ_MAX
};

/* kernel constants */
struct ckpt_const {
	/* task */
	uint16_t task_comm_len;
	/* mm */
	uint16_t at_vector_size;
	/* signal */
	uint16_t signal_nsig;
	/* uts */
	uint16_t uts_sysname_len;
	uint16_t uts_nodename_len;
	uint16_t uts_release_len;
	uint16_t uts_version_len;
	uint16_t uts_machine_len;
	uint16_t uts_domainname_len;
	/* rlimit */
	uint16_t rlimit_nlimits;
	/* tty */
	uint16_t n_tty_buf_size;
	uint16_t tty_termios_nccs;
} __attribute__((aligned(8)));

/* checkpoint image header */
struct ckpt_hdr_header {
	struct ckpt_hdr h;
	uint64_t magic;

	uint16_t arch_id;

	uint16_t major;
	uint16_t minor;
	uint16_t patch;
	uint16_t rev;

	struct ckpt_const constants;

	uint64_t time;	/* when checkpoint taken */
	uint64_t uflags;	/* uflags from checkpoint */

	/*
	 * the header is followed by three strings:
	 *   char release[const.uts_release_len];
	 *   char version[const.uts_version_len];
	 *   char machine[const.uts_machine_len];
	 */
} __attribute__((aligned(8)));

///* checkpoint image trailer */
//struct ckpt_hdr_tail {
//	struct ckpt_hdr h;
//	uint64_t magic;
//} __attribute__((aligned(8)));
//
///* container configuration section header */
//struct ckpt_hdr_container {
//	struct ckpt_hdr h;
//	/*
//	 * the header is followed by the string:
//	 *   char lsm_name[SECURITY_NAME_MAX + 1]
//	 * plus the CKPT_HDR_LSM_INFO section
//	 */
//} __attribute__((aligned(8)));;

/* pids array */
struct ckpt_hdr_pids {
	struct ckpt_hdr h;
	uint32_t nr_pids;
	uint32_t nr_vpids;
	uint32_t offset;  /* objref of the first (root) pid */
} __attribute__((aligned(8)));

struct ckpt_pids {
	uint32_t depth;
	int32_t numbers[1];
} __attribute__((aligned(8)));

///* task tree */
//struct ckpt_hdr_tree {
//	struct ckpt_hdr h;
//	uint32_t nr_tasks;
//} __attribute__((aligned(8)));
//
//struct ckpt_task_pids {
//	/* These pids are in the root_nsproxy's pid ns */
//	__s32 vpid;
//	__s32 vppid;
//	__s32 vtgid;
//	__s32 vpgid;
//	__s32 vsid;
//	uint32_t depth;
//} __attribute__((aligned(8)));
//
///* (negative but not valid error) */
//#define CKPT_PID_NULL  (-4096)  /* null pid pointer */
//#define CKPT_PID_ROOT  (-4097)  /* pid same as root task */
//
///* task data */
//struct ckpt_hdr_task {
//	struct ckpt_hdr h;
//	uint32_t flags;
//	uint32_t state;
//	uint32_t exit_state;
//	uint32_t exit_code;
//	uint32_t exit_signal;
//	uint32_t pdeath_signal;
//
//	uint64_t set_child_tid;
//	uint64_t clear_child_tid;
//	uint64_t sas_ss_sp;
//	uint32_t sas_ss_size;
//
//	uint32_t compat_robust_futex_head_len;
//	uint32_t compat_robust_futex_list; /* a compat __user ptr */
//	uint32_t robust_futex_head_len;
//	uint64_t robust_futex_list; /* a __user ptr */
//
//#ifdef CONFIG_AUDITSYSCALL
//	/* would audit want to track the checkpointed ids,
//	   or (more likely) who actually restarted? */
//#endif
//} __attribute__((aligned(8)));
//
//
//#define CKPT_PF_FORKNOEXEC	0x1
//#define CKPT_PF_SUPERPRIV	0x2
//#define CKPT_PF_VALID		(CKPT_PF_FORKNOEXEC | CKPT_PF_SUPERPRIV)
//
///* Posix capabilities */
//struct ckpt_capabilities {
//	uint32_t cap_i_0, cap_i_1; /* inheritable set */
//	uint32_t cap_p_0, cap_p_1; /* permitted set */
//	uint32_t cap_e_0, cap_e_1; /* effective set */
//	uint32_t cap_b_0, cap_b_1; /* bounding set */
//	uint32_t securebits;
//	uint32_t padding;
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_task_creds {
//	struct ckpt_hdr h;
//	__s32 cred_ref;
//	__s32 ecred_ref;
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_cred {
//	struct ckpt_hdr h;
//	uint32_t uid, suid, euid, fsuid;
//	uint32_t gid, sgid, egid, fsgid;
//	__s32 user_ref;
//	__s32 groupinfo_ref;
//	__s32 sec_ref;
//	struct ckpt_capabilities cap_s;
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_groupinfo {
//	struct ckpt_hdr h;
//	uint32_t ngroups;
//	/*
//	 * This is followed by ngroups __u32s
//	 */
//	uint32_t groups[0];
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_lsm {
//	struct ckpt_hdr h;
//	__s32 ptrref;
//	__u8 sectype;
//	/*
//	 * This is followed by a string of size len+1,
//	 * null-terminated
//	 */
//} __attribute__((aligned(8)));
///*
// * todo - keyrings and LSM
// * These may be better done with userspace help though
// */
//struct ckpt_hdr_user_struct {
//	struct ckpt_hdr h;
//	uint32_t uid;
//	__s32 userns_ref;
//} __attribute__((aligned(8)));
//
///*
// * The user-struct mostly tracks system resource usage.
// * Most of it's contents therefore will simply be set
// * correctly as restart opens resources
// */
//struct ckpt_hdr_user_ns {
//	struct ckpt_hdr h;
//	__s32 creator_ref;
//} __attribute__((aligned(8)));
//
///* namespaces */
//struct ckpt_hdr_task_ns {
//	struct ckpt_hdr h;
//	__s32 ns_objref;
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_ns {
//	struct ckpt_hdr h;
//	__s32 uts_objref;
//	__s32 ipc_objref;
//	__s32 net_objref;
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_task_sem_undo_list {
//	struct ckpt_hdr h;
//	uint32_t count;
//};
//
//struct ckpt_hdr_task_sem_undo {
//	struct ckpt_hdr h;
//	uint32_t semid;
//	uint32_t semadj_count;
//};
//
///* cannot include <linux/tty.h> from userspace, so define: */
//#define CKPT_NEW_UTS_LEN  64
//#ifdef __KERNEL__
//#include <linux/utsname.h>
//#if CKPT_NEW_UTS_LEN != __NEW_UTS_LEN
//#error CKPT_NEW_UTS_LEN size is wrong per linux/utsname.h
//#endif
//#endif
//
//struct ckpt_hdr_utsns {
//	struct ckpt_hdr h;
//	char sysname[CKPT_NEW_UTS_LEN + 1];
//	char nodename[CKPT_NEW_UTS_LEN + 1];
//	char release[CKPT_NEW_UTS_LEN + 1];
//	char version[CKPT_NEW_UTS_LEN + 1];
//	char machine[CKPT_NEW_UTS_LEN + 1];
//	char domainname[CKPT_NEW_UTS_LEN + 1];
//} __attribute__((aligned(8)));
//
///* task's shared resources */
//struct ckpt_hdr_task_objs {
//	struct ckpt_hdr h;
//
//	__s32 files_objref;
//	__s32 mm_objref;
//	__s32 fs_objref;
//	__s32 sem_undo_objref;
//	__s32 sighand_objref;
//	__s32 signal_objref;
//} __attribute__((aligned(8)));
//
///* restart blocks */
//struct ckpt_hdr_restart_block {
//	struct ckpt_hdr h;
//	uint64_t function_type;
//	uint64_t arg_0;
//	uint64_t arg_1;
//	uint64_t arg_2;
//	uint64_t arg_3;
//	uint64_t arg_4;
//} __attribute__((aligned(8)));
//
//enum restart_block_type {
//	CKPT_RESTART_BLOCK_NONE = 1,
//#define CKPT_RESTART_BLOCK_NONE CKPT_RESTART_BLOCK_NONE
//	CKPT_RESTART_BLOCK_HRTIMER_NANOSLEEP,
//#define CKPT_RESTART_BLOCK_HRTIMER_NANOSLEEP \
//		CKPT_RESTART_BLOCK_HRTIMER_NANOSLEEP
//	CKPT_RESTART_BLOCK_POSIX_CPU_NANOSLEEP,
//#define CKPT_RESTART_BLOCK_POSIX_CPU_NANOSLEEP \
//		CKPT_RESTART_BLOCK_POSIX_CPU_NANOSLEEP
//	CKPT_RESTART_BLOCK_COMPAT_NANOSLEEP,
//#define CKPT_RESTART_BLOCK_COMPAT_NANOSLEEP \
//		CKPT_RESTART_BLOCK_COMPAT_NANOSLEEP
//	CKPT_RESTART_BLOCK_COMPAT_CLOCK_NANOSLEEP,
//#define CKPT_RESTART_BLOCK_COMPAT_CLOCK_NANOSLEEP \
//		CKPT_RESTART_BLOCK_COMPAT_CLOCK_NANOSLEEP
//	CKPT_RESTART_BLOCK_POLL,
//#define CKPT_RESTART_BLOCK_POLL CKPT_RESTART_BLOCK_POLL
//	CKPT_RESTART_BLOCK_FUTEX,
//#define CKPT_RESTART_BLOCK_FUTEX CKPT_RESTART_BLOCK_FUTEX
//};
//
///* file system */
//struct ckpt_hdr_fs {
//	struct ckpt_hdr h;
//	uint32_t umask;
//	/* char *fs_root */
//	/* char *fs_pwd */
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_file_table {
//	struct ckpt_hdr h;
//	__s32 fdt_nfds;
//} __attribute__((aligned(8)));
//
///* file descriptors */
//struct ckpt_hdr_file_desc {
//	struct ckpt_hdr h;
//	__s32 fd_objref;
//	__s32 fd_descriptor;
//	uint32_t fd_close_on_exec;
//} __attribute__((aligned(8)));
//
//enum file_type {
//	CKPT_FILE_IGNORE = 0,
//#define CKPT_FILE_IGNORE CKPT_FILE_IGNORE
//	CKPT_FILE_GENERIC,
//#define CKPT_FILE_GENERIC CKPT_FILE_GENERIC
//	CKPT_FILE_PIPE,
//#define CKPT_FILE_PIPE CKPT_FILE_PIPE
//	CKPT_FILE_FIFO,
//#define CKPT_FILE_FIFO CKPT_FILE_FIFO
//	CKPT_FILE_SOCKET,
//#define CKPT_FILE_SOCKET CKPT_FILE_SOCKET
//	CKPT_FILE_TTY,
//#define CKPT_FILE_TTY CKPT_FILE_TTY
//	CKPT_FILE_EPOLL,
//#define CKPT_FILE_EPOLL CKPT_FILE_EPOLL
//	CKPT_FILE_EVENTFD,
//#define CKPT_FILE_EVENTFD CKPT_FILE_EVENTFD
//	CKPT_FILE_MAX
//#define CKPT_FILE_MAX CKPT_FILE_MAX
//};
//
///* file objects */
//struct ckpt_hdr_file {
//	struct ckpt_hdr h;
//	uint32_t f_type;
//	uint32_t f_mode;
//	uint32_t f_flags;
//	__s32 f_credref;
//	uint64_t f_pos;
//	uint64_t f_version;
//	__s32 f_secref;
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_file_generic {
//	struct ckpt_hdr_file common;
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_file_pipe {
//	struct ckpt_hdr_file common;
//	__s32 pipe_objref;
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_file_eventfd {
//	struct ckpt_hdr_file common;
//	uint64_t count;
//	uint32_t flags;
//} __attribute__((aligned(8)));
//
///* socket */
//struct ckpt_hdr_socket {
//	struct ckpt_hdr h;
//
//	__u8 has_buffers;
//
//	struct { /* struct socket */
//		uint64_t flags;
//		__u8 state;
//	} socket __attribute__ ((aligned(8)));
//
//	struct { /* struct sock_common */
//		uint32_t bound_dev_if;
//		uint32_t reuse;
//		uint16_t family;
//		__u8 state;
//	} sock_common __attribute__ ((aligned(8)));
//
//	struct { /* struct sock */
//		__s64 rcvlowat;
//		uint64_t flags;
//
//		__s64 rcvtimeo;
//		__s64 sndtimeo;
//
//		uint32_t err;
//		uint32_t err_soft;
//		uint32_t priority;
//		__s32 rcvbuf;
//		__s32 sndbuf;
//		uint16_t type;
//		__s16 backlog;
//
//		__u8 protocol;
//		__u8 state;
//		__u8 shutdown;
//		__u8 userlocks;
//		__u8 no_check;
//
//		struct linger linger;
//	} sock __attribute__ ((aligned(8)));
//} __attribute__ ((aligned(8)));
//
//struct ckpt_hdr_socket_queue {
//	struct ckpt_hdr h;
//	uint32_t skb_count;
//	uint32_t total_bytes;
//} __attribute__ ((aligned(8)));
//
//struct ckpt_hdr_socket_buffer {
//	struct ckpt_hdr h;
//	uint32_t transport_header;
//	uint32_t network_header;
//	uint32_t mac_header;
//	uint32_t lin_len; /* Length of linear data */
//	uint32_t frg_len; /* Length of fragment data */
//	uint32_t skb_len; /* Length of skb (adjusted) */
//	uint32_t hdr_len; /* Length of skipped header */
//	uint32_t mac_len;
//	uint32_t data_offset; /* Offset of data pointer from head */
//	__s32 sk_objref;
//	__s32 pr_objref;
//	uint16_t protocol;
//	uint16_t nr_frags;
//	__u8 cb[48];
//};
//
//struct ckpt_hdr_socket_buffer_frag {
//	struct ckpt_hdr h;
//	uint32_t size;
//	uint32_t offset;
//};
//
//#define CKPT_UNIX_LINKED 1
//struct ckpt_hdr_socket_unix {
//	struct ckpt_hdr h;
//	__s32 this;
//	__s32 peer;
//	__s32 peercred;
//	uint32_t flags;
//	uint32_t laddr_len;
//	uint32_t raddr_len;
//	struct sockaddr_un laddr;
//	struct sockaddr_un raddr;
//} __attribute__ ((aligned(8)));
//
//struct ckpt_hdr_socket_inet {
//	struct ckpt_hdr h;
//	uint32_t daddr;
//	uint32_t rcv_saddr;
//	uint32_t saddr;
//	uint16_t dport;
//	uint16_t num;
//	uint16_t sport;
//	__s16 uc_ttl;
//	uint16_t cmsg_flags;
//
//	struct {
//		uint64_t timeout;
//		uint32_t ato;
//		uint32_t lrcvtime;
//		uint16_t last_seg_size;
//		uint16_t rcv_mss;
//		__u8 pending;
//		__u8 quick;
//		__u8 pingpong;
//		__u8 blocked;
//	} icsk_ack __attribute__ ((aligned(8)));
//
//	/* FIXME: Skipped opt, tos, multicast, cork settings */
//
//	struct {
//		uint32_t rcv_nxt;
//		uint32_t copied_seq;
//		uint32_t rcv_wup;
//		uint32_t snd_nxt;
//		uint32_t snd_una;
//		uint32_t snd_sml;
//		uint32_t rcv_tstamp;
//		uint32_t lsndtime;
//
//		uint32_t snd_wl1;
//		uint32_t snd_wnd;
//		uint32_t max_window;
//		uint32_t mss_cache;
//		uint32_t window_clamp;
//		uint32_t rcv_ssthresh;
//		uint32_t frto_highmark;
//
//		uint32_t srtt;
//		uint32_t mdev;
//		uint32_t mdev_max;
//		uint32_t rttvar;
//		uint32_t rtt_seq;
//
//		uint32_t packets_out;
//		uint32_t retrans_out;
//
//		uint32_t snd_up;
//		uint32_t rcv_wnd;
//		uint32_t write_seq;
//		uint32_t pushed_seq;
//		uint32_t lost_out;
//		uint32_t sacked_out;
//		uint32_t fackets_out;
//		uint32_t tso_deferred;
//		uint32_t bytes_acked;
//
//		__s32 lost_cnt_hint;
//		uint32_t retransmit_high;
//
//		uint32_t lost_retrans_low;
//
//		uint32_t prior_ssthresh;
//		uint32_t high_seq;
//
//		uint32_t retrans_stamp;
//		uint32_t undo_marker;
//		__s32 undo_retrans;
//		uint32_t total_retrans;
//
//		uint32_t urg_seq;
//		uint32_t keepalive_time;
//		uint32_t keepalive_intvl;
//
//		uint16_t urg_data;
//		uint16_t advmss;
//		__u8 frto_counter;
//		__u8 nonagle;
//
//		__u8 ecn_flags;
//		__u8 reordering;
//
//		__u8 keepalive_probes;
//	} tcp __attribute__ ((aligned(8)));
//
//	struct {
//		struct in6_addr saddr;
//		struct in6_addr rcv_saddr;
//		struct in6_addr daddr;
//	} inet6 __attribute__ ((aligned(8)));
//
//	uint32_t laddr_len;
//	uint32_t raddr_len;
//	struct sockaddr_in laddr;
//	struct sockaddr_in raddr;
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_file_socket {
//	struct ckpt_hdr_file common;
//	__s32 sock_objref;
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_netns {
//	struct ckpt_hdr h;
//	__s32 this_ref;
//} __attribute__((aligned(8)));
//
//enum ckpt_netdev_types {
//	CKPT_NETDEV_LO,
//	CKPT_NETDEV_VETH,
//	CKPT_NETDEV_SIT,
//	CKPT_NETDEV_MACVLAN,
//	CKPT_NETDEV_MAX,
//};
//
//struct ckpt_hdr_netdev {
//	struct ckpt_hdr h;
//	__s32 netns_ref;
//	union {
//		struct {
//			__s32 this_ref;
//			__s32 peer_ref;
//		} veth;
//		struct {
//			uint32_t mode;
//		} macvlan;
//	};
//	uint32_t inet_addrs;
//	uint16_t type;
//	uint16_t flags;
//	__u8 hwaddr[6];
//} __attribute__((aligned(8)));
//
//enum ckpt_netdev_addr_types {
//	CKPT_NETDEV_ADDR_IPV4,
//};
//
//struct ckpt_netdev_addr {
//	uint16_t type;
//	union {
//		struct {
//			__be32 inet4_local;
//			__be32 inet4_address;
//			__be32 inet4_mask;
//			__be32 inet4_broadcast;
//		};
//	} __attribute__((aligned(8)));
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_eventpoll_items {
//	struct ckpt_hdr h;
//	__s32  epfile_objref;
//	uint32_t  num_items;
//} __attribute__((aligned(8)));
//
///* Contained in a CKPT_HDR_BUFFER following the ckpt_hdr_eventpoll_items */
//struct ckpt_eventpoll_item {
//	uint64_t data;
//	uint32_t fd;
//	__s32 file_objref;
//	uint32_t events;
//} __attribute__((aligned(8)));
//
///* memory layout */
//struct ckpt_hdr_mm {
//	struct ckpt_hdr h;
//	uint32_t map_count;
//	__s32 exe_objref;
//
//	uint64_t def_flags;
//	uint64_t flags;
//
//	uint64_t start_code, end_code, start_data, end_data;
//	uint64_t start_brk, brk, start_stack;
//	uint64_t arg_start, arg_end, env_start, env_end;
//} __attribute__((aligned(8)));
//
///* vma subtypes - index into restore_vma_dispatch[] */
//enum vma_type {
//	CKPT_VMA_IGNORE = 0,
//#define CKPT_VMA_IGNORE CKPT_VMA_IGNORE
//	CKPT_VMA_VDSO,		/* special vdso vma */
//#define CKPT_VMA_VDSO CKPT_VMA_VDSO
//	CKPT_VMA_ANON,		/* private anonymous */
//#define CKPT_VMA_ANON CKPT_VMA_ANON
//	CKPT_VMA_FILE,		/* private mapped file */
//#define CKPT_VMA_FILE CKPT_VMA_FILE
//	CKPT_VMA_SHM_ANON,	/* shared anonymous */
//#define CKPT_VMA_SHM_ANON CKPT_VMA_SHM_ANON
//	CKPT_VMA_SHM_ANON_SKIP,	/* shared anonymous (skip contents) */
//#define CKPT_VMA_SHM_ANON_SKIP CKPT_VMA_SHM_ANON_SKIP
//	CKPT_VMA_SHM_FILE,	/* shared mapped file, only msync */
//#define CKPT_VMA_SHM_FILE CKPT_VMA_SHM_FILE
//	CKPT_VMA_SHM_IPC,	/* shared sysvipc */
//#define CKPT_VMA_SHM_IPC CKPT_VMA_SHM_IPC
//	CKPT_VMA_SHM_IPC_SKIP,	/* shared sysvipc (skip contents) */
//#define CKPT_VMA_SHM_IPC_SKIP CKPT_VMA_SHM_IPC_SKIP
//	CKPT_VMA_HUGETLB,
//#define CKPT_VMA_HUGETLB CKPT_VMA_HUGETLB
//	CKPT_VMA_HUGETLB_SKIP,
//#define CKPT_VMA_HUGETLB_SKIP CKPT_VMA_HUGETLB_SKIP
//};
//
///* vma descriptor */
//struct ckpt_hdr_vma {
//	struct ckpt_hdr h;
//	uint32_t vma_type;
//	__s32 vma_objref;	/* objref of backing file */
//	__s32 ino_objref;	/* objref of shared segment */
//	uint32_t _padding;
//	uint64_t ino_size;		/* size of shared segment */
//
//	uint64_t vm_start;
//	uint64_t vm_end;
//	uint64_t vm_page_prot;
//	uint64_t vm_flags;
//	uint64_t vm_pgoff;
//
//	uint16_t hugetlb_shift;
//} __attribute__((aligned(8)));
//
///* page array */
//struct ckpt_hdr_pgarr {
//	struct ckpt_hdr h;
//	uint64_t nr_pages;		/* number of pages to saved */
//} __attribute__((aligned(8)));
//
///* huge page */
//struct ckpt_hdr_hpage {
//	struct ckpt_hdr h;
//	union {
//		uint64_t vaddr;
//		uint64_t index;
//	};
//	uint16_t shift;
//} __attribute__((aligned(8)));
//
///* signals */
//struct ckpt_sigset {
//	__u8 sigset[CKPT_ARCH_NSIG / 8];
//} __attribute__((aligned(8)));
//
//struct ckpt_sigaction {
//	uint64_t _sa_handler;
//	uint64_t sa_flags;
//	uint64_t sa_restorer;
//	struct ckpt_sigset sa_mask;
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_sighand {
//	struct ckpt_hdr h;
//	struct ckpt_sigaction action[0];
//} __attribute__((aligned(8)));
//
//struct ckpt_siginfo {
//	uint32_t csi_signo;
//	__s32 csi_errno;
//	__s32 csi_code;
//	uint32_t csi_pid;
//	uint32_t csi_uid;
//	__s32 csi_fd;
//	uint32_t csi_tid;
//	uint32_t csi_band;
//	uint32_t csi_overrun;
//	uint32_t csi_trapno;
//	__s32 csi_status;
//	__s32 csi_int;
//	uint64_t csi_ptr;
//	uint64_t csi_utime;
//	uint64_t csi_stime;
//	uint64_t csi_addr;
//	__s32 csi_sys_private; /* POSIX.1b timers */
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_sigpending {
//	struct ckpt_hdr h;
//	uint32_t nr_pending;
//	struct ckpt_sigset signal;
//	struct ckpt_siginfo siginfo[0];
//} __attribute__((aligned(8)));
//
//struct ckpt_rlimit {
//	uint64_t rlim_cur;
//	uint64_t rlim_max;
//} __attribute__((aligned(8)));

/* cannot include <linux/resource.h> from userspace, so define: */
#define CKPT_RLIM_NLIMITS  16
// U11 : temporatly define TODO : resource.h
#define RLIM_NLIMITS CKPT_RLIM_NLIMITS
//#ifdef __KERNEL__
//#include <linux/resource.h>
//#if CKPT_RLIM_NLIMITS != RLIM_NLIMITS
//#error CKPT_RLIM_NLIMIT size is wrong per asm-generic/resource.h
//#endif
//#endif

//struct ckpt_hdr_signal {
//	struct ckpt_hdr h;
//	/* rlimit */
//	struct ckpt_rlimit rlim[CKPT_RLIM_NLIMITS];
//	/* itimer */
//	uint64_t it_real_value;
//	uint64_t it_real_incr;
//	uint64_t it_virt_value;
//	uint64_t it_virt_incr;
//	uint64_t it_prof_value;
//	uint64_t it_prof_incr;
//	/* tty */
//	__s32 tty_objref;
//	__s32 tty_pgrp;
//	__s32 tty_old_pgrp;
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_signal_task {
//	struct ckpt_hdr h;
//	struct ckpt_sigset blocked;
//} __attribute__((aligned(8)));
//
///* ipc commons */
//struct ckpt_hdr_ipcns {
//	struct ckpt_hdr h;
//	uint64_t shm_ctlmax;
//	uint64_t shm_ctlall;
//	__s32 shm_ctlmni;
//
//	__s32 msg_ctlmax;
//	__s32 msg_ctlmnb;
//	__s32 msg_ctlmni;
//
//	__s32 sem_ctl_msl;
//	__s32 sem_ctl_mns;
//	__s32 sem_ctl_opm;
//	__s32 sem_ctl_mni;
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_ipc {
//	struct ckpt_hdr h;
//	uint32_t ipc_type;
//	uint32_t ipc_count;
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_ipc_perms {
//	struct ckpt_hdr h;
//	__s32 id;
//	uint32_t key;
//	uint32_t uid;
//	uint32_t gid;
//	uint32_t cuid;
//	uint32_t cgid;
//	uint32_t mode;
//	uint32_t _padding;
//	uint64_t seq;
//	__s32 sec_ref;
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_ipc_shm {
//	struct ckpt_hdr h;
//	struct ckpt_hdr_ipc_perms perms;
//	uint64_t shm_segsz;
//	uint64_t shm_atim;
//	uint64_t shm_dtim;
//	uint64_t shm_ctim;
//	__s32 shm_cprid;
//	__s32 shm_lprid;
//	uint32_t mlock_uid;
//	uint32_t flags;
//	uint32_t objref;
//	uint16_t shift;  /* hugetlb */
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_ipc_msg {
//	struct ckpt_hdr h;
//	struct ckpt_hdr_ipc_perms perms;
//	uint64_t q_stime;
//	uint64_t q_rtime;
//	uint64_t q_ctime;
//	uint64_t q_cbytes;
//	uint64_t q_qnum;
//	uint64_t q_qbytes;
//	__s32 q_lspid;
//	__s32 q_lrpid;
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_ipc_msg_msg {
//	struct ckpt_hdr h;
//	__s64 m_type;
//	uint32_t m_ts;
//	__s32 sec_ref;
//} __attribute__((aligned(8)));
//
//struct ckpt_hdr_ipc_sem {
//	struct ckpt_hdr h;
//	struct ckpt_hdr_ipc_perms perms;
//	uint64_t sem_otime;
//	uint64_t sem_ctime;
//	uint32_t sem_nsems;
//} __attribute__((aligned(8)));
//
//
///* devices */
//struct ckpt_hdr_file_tty {
//	struct ckpt_hdr_file common;
//	__s32 tty_objref;
//};
//
//struct ckpt_hdr_tty {
//	struct ckpt_hdr h;
//
//	uint16_t driver_type;
//	uint16_t driver_subtype;
//
//	__s32 link_objref;
//	__s32 file_objref;
//	uint32_t _padding;
//
//	uint32_t index;
//	uint32_t ldisc;
//	uint64_t flags;
//
//	/* termios */
//	struct {
//		uint32_t c_iflag;
//		uint32_t c_oflag;
//		uint32_t c_cflag;
//		uint32_t c_lflag;
//		uint32_t c_ispeed;
//		uint32_t c_ospeed;
//		__u8 c_line;
//		__u8 c_cc[NCCS];
//	} __attribute__((aligned(8))) termios;
//
//	/* winsize */
//	struct {
//		uint16_t ws_row;
//		uint16_t ws_col;
//		uint16_t ws_xpixel;
//		uint16_t ws_ypixel;
//	} __attribute__((aligned(8))) winsize;
//} __attribute__((aligned(8)));
//
///* cannot include <linux/tty.h> from userspace, so define: */
//#define CKPT_N_TTY_BUF_SIZE  4096
//#ifdef __KERNEL__
//#include <linux/tty.h>
//#if CKPT_N_TTY_BUF_SIZE != N_TTY_BUF_SIZE
//#error CKPT_N_TTY_BUF_SIZE size is wrong per linux/tty.h
//#endif
//#endif
//
//struct ckpt_hdr_ldisc_n_tty {
//	struct ckpt_hdr h;
//
//	uint32_t column;
//	uint32_t datalen;
//	uint32_t canon_column;
//	uint32_t canon_datalen;
//	uint32_t canon_data;
//
//	uint16_t minimum_to_wake;
//
//	__u8 stopped;
//	__u8 hw_stopped;
//	__u8 flow_stopped;
//	__u8 packet;
//	__u8 ctrl_status;
//	__u8 lnext;
//	__u8 erasing;
//	__u8 raw;
//	__u8 real_raw;
//	__u8 icanon;
//	__u8 closing;
//	__u8 padding[3];
//
//	__u8 read_flags[CKPT_N_TTY_BUF_SIZE / 8];
//
//	/* if @datalen > 0, buffer contents follow (next object) */
//} __attribute__((aligned(8)));
//
//
//#define CKPT_TST_OVERFLOW_16(a, b) \
//	((sizeof(a) > sizeof(b)) && ((a) > SHRT_MAX))
//
//#define CKPT_TST_OVERFLOW_32(a, b) \
//	((sizeof(a) > sizeof(b)) && ((a) > INT_MAX))
//
//#define CKPT_TST_OVERFLOW_64(a, b) \
//	((sizeof(a) > sizeof(b)) && ((a) > LONG_MAX))


#endif /* _CHECKPOINT_CKPT_HDR_H_ */
